package org.dromara.system.elastic;

import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.protocol.HttpContext;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;

@Configuration
public class ElasticsearchConfig {

    @Value("${spring.elasticsearch.uris}")
    private String uris;

    @Value("${spring.elasticsearch.username}")
    private String username;

    @Value("${spring.elasticsearch.password}")
    private String password;

    private RestHighLevelClient client;

    @Autowired
    private ElasticsearchTemplate restTemplate;

    @PostConstruct
    public void init() {
        String[] uriArray = uris.split(","); // 假设可能有多个URIs，用逗号分隔
        HttpHost[] httpHosts = new HttpHost[uriArray.length];
        for (int i = 0; i < uriArray.length; i++) {
            // 这里可能需要更复杂的解析，特别是如果URI包含scheme、路径等
            // 但对于简单的http://host:port，下面的解析应该足够了
            String[] parts = uriArray[i].split("://");
            String[] hostPort = parts[1].split(":");
            httpHosts[i] = new HttpHost(hostPort[0], Integer.parseInt(hostPort[1]), "http");
        }

        // 使用带有基本身份验证的RestClient.builder
        RestClientBuilder builder = RestClient.builder(httpHosts);
        if (username != null && !username.isEmpty() && password != null && !password.isEmpty()) {
            CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials(username, password));
            builder.setHttpClientConfigCallback(builder1 -> {
                // 设置自定义的保活策略
                builder1.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy() {
                    @Override
                    public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
                        // 返回你想要的保活时间，例如60秒
                        return 30 * 1000;
                    }
                });
                return builder1.setDefaultCredentialsProvider(credentialsProvider);
            });
        }

        client = new RestHighLevelClient(builder);
    }

//    // 处理配置刷新事件
//    @RefreshScope
//    public void onRefresh() {
//        // 关闭旧的客户端
//        close();
//        // 重新初始化客户端
//        init();
//    }

    @Bean
    public RestHighLevelClient restHighLevelClient() {
        return client;
    }

    @PreDestroy
    public void close() {
        try {
            if (client != null) {
                client.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Scheduled(fixedRate = 30000) // 每分钟执行一次
    public void keepElasticsearchTemplateAlive() {
        try {
            boolean index = client.ping(RequestOptions.DEFAULT);
            String version = restTemplate.getClusterVersion();
//            System.out.printf("Es: " + index + " version " + version + "\n");
        }catch (Exception ignore){}
    }
}
